const moment = require("moment");
const cryptoUtils = require("../utils/crypto");
const Base = require("./base");
const { where } = require("sequelize");
const DEFAULT_USER_PRFIX = "@AU@_";
module.exports = class User extends Base {
  register(params) {
    return this.addUser(params).then((uid) => this.findOne({ uid }));
  }

  thirdAuth(params) {
    const { openid } = params;
    return this.app.mysql
      .use("user")
      .query(`SELECT uid,isbind FROM third_auth WHERE openid='${openid}'`)
      .then((res) => res[0][0])
      .then(async (res) => {
        console.log("thirdAuth==>", res);
        let uid;
        // 如果存在用户查询用户，否则就注册一个新用户
        if (res) {
          if (res.isbind === 0) {
            await this.updateThirdbindStatus({ openid });
          }
          uid = res.uid;
        } else {
          uid = await this.createThirdAuthUser(params);
        }
        const result = await this.findOne({ uid });
        return result;
      });
  }
  thirdAuthBind(params) {
    const { openid, uid } = params;
    const userDB = this.app.mysql.use("user");
    return userDB
      .query(`SELECT * FROM third_auth WHERE openid='${openid}'`)
      .then((res) => res[0][0])
      .then((res) => {
        // 如果存在用户,说明已经授权过或者绑定到其它用户
        if (res) {
          // 能查询出信息，当用户uid相同时，说明之前绑定后被解绑，现需要重新绑定
          if (res.isbind == 0) {
            return this.updateThirdbindStatus({ openid, uid }).then((_) => 0);
          }
          return -1;
        } else {
          return this.insertThirdAuth(params).then((_) => 0);
        }
      });
  }
  updateThirdbindStatus(params, isbind = 1) {
    const { uid, openid } = params;
    const value = [`isbind=${isbind}`];
    if (uid) {
      value.push(`uid='${uid}'`);
    }
    // 更新用户绑定
    return this.app.mysql
      .use("user")
      .query(`UPDATE third_auth SET ${value.join()} WHERE openid='${openid}'`)
      .then((res) => res[0])
      .then((res) => {
        if (res) {
          return res.changedRows;
        } else {
          return 0;
        }
      });
  }

  // 创建三方授权用户
  async createThirdAuthUser(params) {
    const { openid, unionid, type } = params;
    console.log(params, "createThirdAuthUser");
    // 自动注册一个用户时生成唯一uid
    const uid = this._uid(openid);
    params.uid = uid;
    // 三方授权登录直接生成一个默认用户名，用户名以uid
    params.username = `${DEFAULT_USER_PRFIX}${uid}`;
    await this.insertThirdAuth({
      openid,
      unionid,
      type,
      uid,
    });

    // 删除掉
    delete params.openid;
    delete params.unionid;
    delete params.type;

    return this.addUser(params);
  }

  insertThirdAuth(params) {
    const { keys, replacements, values } = this.installParams(params);
    // 写入授权
    return this.app.mysql
      .use("user")
      .query(`INSERT INTO third_auth(${keys}) VALUES(${values})`, {
        replacements,
      });
  }

  // 更新用户VIP时间
  updateExprise(params) {
    return this.app.mysql
      .use("user")
      .query(
        `UPDATE user SET vip_expire='${params.vip_expire}' WHERE uid='${params.uid}'`
      );
  }

  getUserSet(params) {
    const { type = "", uid, version } = params;
    const expr = [`uid='${uid}'`];
    if (type) {
      expr.push(`type='${type}'`);
    }
    const db = this.app.mysql.use("user");
    let sel = '*';
    if(version< '1.0.5') {
      sel = 'id,uid,`type` AS save_key ,`value` AS save_value,create_time,update_time'
    }
    return db
      .query(`SELECT ${sel} FROM user_set WHERE ${expr.join(" AND ")}`)
      .then((res) => res[0]);
  }
  putUserSet(params) {
    const { keys, replacements, values } = this.installParams(params);
    const expr = `WHERE type='${params.type}' AND uid='${params.uid}'`;
    const db = this.app.mysql.use("user");
    return db
      .query(`SELECT COUNT(id) AS counts FROM user_set ${expr}`)
      .then((res) => {
        if (res[0][0].counts > 0) {
          return db.query(
            `UPDATE user_set SET value='${params.value}' ${expr}`
          );
        } else {
          return db.query(`INSERT INTO user_set(${keys}) VALUES(${values})`, {
            replacements,
          });
        }
      });
  }
  /**
   * @function 添加用户，返回添加用户信息
   * @params {Object} data 用户相关字段
   * {
   *  type: // 分类类型，Null代表公用类型, 1代表漫画，2代表音乐
   * }
   */
  addUser(params) {
    let { password, uid, username, avatar } = params;
    const mixin = this.config.mixin || {};
    // 创建用户时，指定用户初使密码为默认12345678
    params.password = this._encryptPassword(password ? password : "12345678");
    if (!uid) {
      // 注册一个用户时生成唯一uid
      uid = this._uid(username + mixin.salt + moment.now());
      params.uid = uid;
    }

    // 不存在默认一个图标
    if (!avatar) {
      params.avatar = "https://file.nadu8.com/assets/foindia.png-normal";
    }

    const { keys, replacements, values } = this.installParams(params);
    return this.app.mysql
      .use("user")
      .query(`INSERT INTO user(${keys}) VALUES(${values})`, {
        replacements,
      })
      .then(() => uid);
  }
  /**
   * @function 更新用户
   * @param params
    {
      id: {Number}, // @required 用户id自增
      username: {String}, // 用户名称
      nickusername: {String}, // 用户名字昵称
      password: {String}, // 密码
      phone: {Number}, // 电话号码
      email: {String}, // 邮箱
      status: {Number}, // 用户状态，0表示禁用，1表示启用
      role_id: {Number}, // 用户角色
    }
   */
  update(params) {
    const { id, uid } = params;
    if (params.password) {
      params.password = this._encryptPassword(params.password, true);
    }
    delete params.id;
    const { replacements, values } = this.installParams(params, 2);
    let sql = `UPDATE user SET ${values} WHERE uid="${uid}"`;
    return this.app.mysql
      .use("user")
      .query(sql, {
        replacements,
      })
      .then((res) => res[0])
      .then((res) => res.changedRows);
  }

  /**
   * @function findOne 查找用户
   * @param {String} uid
   * {
      username: {String} @required
      password: {String}
   * }
   */
  async findOne(params) {
    let { password } = params;
    if (password) {
      params.password = this._encryptPassword(password, true);
    }
    const { replacements, values } = this.installParams(params, 1);
    let sql = `SELECT id,uid,avatar,username,nickname,year,gender,phone,email,create_time,update_time,status,level,role_id,country,province,city,vip_expire FROM user WHERE ${values};`;
    const userDB = this.app.mysql.use("user");
    return userDB
      .query(sql, { replacements })
      .then((res) => res[0])
      .then(async (res) => {
        // 如果查询不到数据直接返回
        if (res.length === 0) return null;
        const data = res[0];
        const tripart = await userDB
          .query(this._tripartSQL(data.uid))
          .then((res) => res[0]);
        data.tripart = tripart;
        let username = data.username;
        // 自动生成的用户进程处理

        if (new RegExp(`^${DEFAULT_USER_PRFIX}`).test(username)) {
          username = username.replace(DEFAULT_USER_PRFIX, "").substr(0, 8);
          data.username = username;
          data.updatable_username = true;
        }
        return data;
      })
      .then((res) => {
        return res && this._createToken(res);
      });
  }

  _tripartSQL(uid) {
    return `SELECT uid,type,openid,unionid FROM third_auth WHERE uid='${uid}' AND isbind=1;`;
  }

  /**
   * @function _createToken
   * @param {Object} data
   * @return {Object} 返回用户信息
   */
  async _createToken(userInfo) {
    const mixin = this.config.mixin || {};
    // 设置过期时间
    userInfo.expire = moment()
      .add(mixin.expire[0], mixin.expire[1])
      .format("YYYY-MM-DD hh:mm:ss.SSS");

    // 生成access_token
    userInfo.access_token = cryptoUtils.encryptAes(
      "aes-128-ecb",
      mixin.aesKey,
      "",
      JSON.stringify({
        expire: userInfo.expire,
        id: userInfo.id,
        uid: userInfo.uid,
        openid: userInfo.openid,
        username: userInfo.username,
        password: userInfo.password,
        role_id: userInfo.role_id,
      })
    );

    return userInfo;
  }

  /**
   * @function _createUserid 生成唯一值token
   * @param {Object} userInfo
   * @param {String} key
   */
  _createUserid(data, key) {
    return cryptoUtils.md5(
      cryptoUtils.encryptAes("aes-128-ecb", key, "", data)
    );
  }

  _encryptPassword(password, isDecrypt = false) {
    const { aes, mixin } = this.config;
    if (isDecrypt) {
      password = cryptoUtils.decryptAesMix(password, aes);
    }
    return cryptoUtils.md5(`${password}${mixin.salt}`);
  }

  _uid(value) {
    // 生成用户唯一uid
    const mixin = this.config.mixin || {};
    const uid = this._createUserid(
      `${value}${mixin.salt}}`,
      mixin.aesKey
    ).toLocaleUpperCase();
    return uid;
  }

  userVipInfo(params) {
    let sql = `SELECT vip_expire FROM user WHERE uid='${params.uid}'`;
    return this.app.mysql
      .use("user")
      .query(sql)
      .then((res) => res[0][0]);
  }

  check(params) {
    const { replacements, values } = this.installParams(params, 2);
    let sql = `SELECT uid FROM user WHERE ${values}`;
    return this.app.mysql
      .use("user")
      .query(sql, { replacements })
      .then((res) => res[0][0]);
  }
};
